/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.kota105.xml;

/**
 *
 * @author pikpun
 */
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.kota105.ui.generic.Layout;
import org.kota105.ui.generic.Widget;
import org.kota105.ui.generic.properties.Property;
import org.kota105.util.ClassRetrieval;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class XMLHandler extends DefaultHandler {

    private Stack<Layout> stackLayout;
    private Layout rootLayout;

    public XMLHandler() {
        stackLayout = new Stack<Layout>();
    }

    public void loadFromString(String content)
            throws SAXException, ParserConfigurationException, IOException {
        load(new File(content));
    }

    public void load(File in)
            throws SAXException, ParserConfigurationException, IOException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        parser.parse(in, this);
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        try {
            Constructor ct = ClassRetrieval.getClass(qName).getConstructor();
            Widget widget = (Widget) ct.newInstance();
            if (widget instanceof Layout) {
                stackLayout.push((Layout) setProperties(widget, attributes));
            } else {
                widget = setProperties(widget, attributes);
                stackLayout.get(stackLayout.size() - 1).
                        addWidget(widget);
            }
        } catch (Exception ex) {
            Logger.getLogger(XMLHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private Widget setProperties(Widget widget, Attributes attributes) {
        for (int i = 0; i < attributes.getLength(); i++) {
            if (!attributes.getQName(i).equals("xmlns:android")) {
                Property property = new Property();
                property.setAttributeName(attributes.getQName(i));
                property.setValue(attributes.getValue(i));
                widget.addProperty(property);
            }else{
                ((Layout)widget).setRoot(true);
            }
        }
        return widget;
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        try {
            Constructor ct = ClassRetrieval.getClass(qName).getConstructor();
            Widget w = (Widget) ct.newInstance();
            if (w instanceof Layout) {
                if (stackLayout.size() == 1) {
                    rootLayout = stackLayout.get(0);
                } else {
                    stackLayout.get(stackLayout.size() - 2).addWidget(stackLayout.pop());
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(XMLHandler.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public Layout getRootLayout() {
        return rootLayout;
    }

    public void setRootLayout(Layout rootLayout) {
        this.rootLayout = rootLayout;
    }

    public static void main(String[] args) {
        XMLHandler handler = new XMLHandler();
        try {
            handler.loadFromString("D:/Nitip/Ucup/Liputan 6/res/layout/twitter.xml");
            Layout l = handler.getRootLayout();

            XMLGenerator generator = new XMLGenerator();
            generator.generateXml(l, new File("C:/Users/pikpun/Documents/NetBeansProjects/TesForXML/res/layout/main.xml"));

//            retrieveLayout(l);

        } catch (SAXException ex) {
//            Logger.getLogger(XMLHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
//            Logger.getLogger(XMLHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
//            Logger.getLogger(XMLHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void retrieveLayout(Layout l) {
        System.out.println(l.getXMLName());
        if(l.isRoot()){
            System.out.println("root duluan");
        }
        for (Property p : l.getProperties()) {
            System.out.println(p.getAttributeName() + " = " + p.getValue());
        }
        System.out.println("====================");
        for (Widget widget : l.getWidgets()) {
            if (widget instanceof Layout) {
                retrieveLayout((Layout) widget);
            }
            System.out.println(widget.getXMLName());
            for (Property p : widget.getProperties()) {
                System.out.println(p.getAttributeName() + " = " + p.getValue());
            }
            System.out.println("====================");
        }
    }

}
